//
//  SEInquiryInfoViewModel.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/19.
//

import Foundation
import UIKit

class SEInquiryInfoViewModel: SEBaseViewModel {
    var inquiryInfoList: [SEInquiryInfo] = []
    
    var info = SEInquiryInfo()
    
    var patientInfo = SEPatientDetailViewModel()
    
    var doctorDetail = SEDoctorDetail()
    
    var confirmOnlineReserveSuccess: ((SEHttpStatus) -> Void)?
    var confirmGuideDiagnosisInfoSuccess: ((SEHttpStatus) -> Void)?
    
    convenience init(info: SEInquiryInfo) {
        self.init(withLoading: true)
        self.info = info
    }
    
    var avatarPlaceholder: UIImage {
        doctorDetail.sex == 1 ? Asset.iconDoctorAvatarMale.image : Asset.iconDoctorAvatarFemale.image
    }
    
    var doctorAvatarPlaceholder: UIImage {
        info.doctorSex == 1 ? Asset.iconDoctorAvatarMale.image : Asset.iconDoctorAvatarFemale.image
    }
    
    // MARK: - 线上问诊、导诊消息列表
    
    var dateTime: String {
        if let lastReadTime = info.lastReadTime, !lastReadTime.isEmpty {
            return Date.stringToDate(lastReadTime).chatTimeString
        } else {
            guard let createTime = info.createTime, !createTime.isEmpty else { return "" }
            return Date.stringToDate(createTime).chatTimeString
        }
    }
    
    var numberOfRows: Int { inquiryInfoList.count }
    
    func viewModel(at indexPath: IndexPath) -> SEInquiryInfoViewModel {
        return SEInquiryInfoViewModel(info: inquiryInfoList[indexPath.row])
    }
    
    /// 获取导诊、问诊消息列表
    func getListOfInquiryMessages() {
        SEHttpManager.shared.requestForModelArray(SEHospitalizeAPI.listOfInquiryMessages, model: SEInquiryInfo.self) { (models, httpStatus) in
            switch httpStatus {
            case .success:
                self.inquiryInfoList = models ?? []
                self.encodeMessages()
            default: break
            }
            self.updateData?(httpStatus)
        }
    }
    
    // MARK: - 线上问诊、导诊就诊信息
    
    var hasAllergyHistory: Bool {
        get { info.isAllergic == 1 ? true : false }
        set { info.isAllergic = newValue ? 1 : 0 }
    }
    
    var allergyHistory: String {
        hasAllergyHistory ? info.allergicContent ?? "" : ""
    }
    
    // MARK: - 线上问诊 - 就诊信息填写
    
    /// 是否选择了就诊人
    var patientDidPicked: Bool { !patientInfo.model.id.isEmpty }
    var onlineReserveInfoAllEmpty: Bool {
        conditionDescEmpty && allergyHistoryEmpty && pastHistoryEmpty
    }
    var conditionDescEmpty: Bool { (info.illness ?? "").isEmpty }
    
    var allergyHistoryEmpty: Bool { (hasAllergyHistory ? (info.allergicContent ?? "").isEmpty : false) }
    
    var pastHistoryEmpty: Bool { (info.pastHistory ?? "").isEmpty }
    
    var jobTitleAndDepartment: String {
        let jobTitle = doctorDetail.jobTitle ?? ""
        let department = doctorDetail.deptName ?? ""
        if jobTitle.isEmpty || department.isEmpty {
            return jobTitle + department
        } else {
            return jobTitle + "/" + department
        }
    }
    var patientName: String {
        patientInfo.model.name.isEmpty ? "请选择本次问诊的就诊人" : patientInfo.model.name
    }
    var patientNameColor: UIColor {
        patientInfo.model.name.isEmpty ? UIColor(hex: "#C8C8C8") : Asset.textDark.color
    }
    func hospitalRatingLabelWidth(_ label: UILabel) -> CGFloat {
        guard let rating = doctorDetail.hospitalJb else { return 0 }
        return rating.width(height: label.height, font: label.font) + 3 * 2
    }
    
    var numberOfSectionsForOnlineReserve: Int {
        return 6
    }
    
    func cellHeightForOnlineReserve(at indexPath: IndexPath) -> CGFloat {
        switch indexPath.section {
        case 0: return 66
        case 1: return 44
        case 2, 4: return 120
        case 3: return hasAllergyHistory ? 130 : 0
        case 5: return UITableView.automaticDimension
        default: return 0
        }
    }
    
    func headerHeightForOnlineReserve(in section: Int) -> CGFloat {
        switch section {
        case 0: return kSEOnlineReserveHeaderDefaultHeight
        case 3: return 45
        default: return 0.001
        }
    }
    
    /// 确认线上预约就诊信息
    func confirmOnlineReserveInfo() {
        let api = SEHospitalizeAPI.confirmOnlineReserve(doctorId: doctorDetail.id ?? "", patientId: patientInfo.model.id, illnessDesc: info.illness ?? "", hasAllergyHistory: info.isAllergic, allergyHistory: allergyHistory, pastHistory: info.pastHistory ?? "", imageIds: imageIds)
        SEHttpManager.shared.requestForAny(api, withLoading: true) { (result, httpStatus) in
            switch httpStatus {
            case .success:
                self.info.id = result as? String
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            self.confirmOnlineReserveSuccess?(httpStatus)
        }
    }
    
    /// 获取线上问诊详情
    func getDetailOfOnlineInquiry() {
        SEHttpManager.shared.request(SEHospitalizeAPI.detailOfOnlineInquiry(id: info.id ?? ""), model: SEInquiryInfo.self, withLoading: withLoading) { (model, httpStatus) in
            switch httpStatus {
            case .success:
                self.info = model ?? self.info
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            self.updateData?(httpStatus)
        }
    }
    
    // MARK: - 导诊 - 就诊信息填写
    
    /// 是否在导诊中
    var inGuideInquiry: Bool = false
    
    private var _isAgree = false
    var isAgree: Bool {
        get { _isAgree }
        set { _isAgree = newValue }
    }
    
    var numberOfSectionsForGuideDiagnosisInfo: Int {
        return 3
    }
    
    func cellHeightForGuideDiagnosisInfo(at indexPath: IndexPath) -> CGFloat {
        switch indexPath.section {
        case 0: return 120
        case 1: return hasAllergyHistory ? 100 : 0
        case 2: return (UIScreen.screenWidth - 15 * 4) / 3 + 10
        default: return 0
        }
    }
    
    /// 检查当前是否存在导诊
    func checkCurrentlyInGuideInquiry() {
        SEHttpManager.shared.request(SEHospitalizeAPI.checkCurrentlyInGuideInquiry, model: SEGuideInquiryModel.self, withLoading: withLoading) { (model, httpStatus) in
            switch httpStatus {
            case .success:
                self.info.id = model?.bisId
                self.inGuideInquiry = model?.status == 1
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            self.updateData?(httpStatus)
        }
    }
    
    /// 确认导诊就诊信息
    func confirmGuideDiagnosisInfo() {
        SEHttpManager.shared.request(SEHospitalizeAPI.confirmGuideDiagnosisInfo(illnessDesc: info.illness ?? "", hasAllergyHistory: info.isAllergic, allergyHistory: allergyHistory, imageIds: imageIds), model: SEGuideInquiryModel.self, withLoading: withLoading) { (model, httpStatus) in
            switch httpStatus {
            case .success:
                SEHUD.show(message: "导诊信息提交成功")
                self.info.id = model?.bisId
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            self.confirmGuideDiagnosisInfoSuccess?(httpStatus)
        }
    }
    
    // MARK: - 图片
    
    var imagesCount: Int { info.picList?.count ?? 0 }
    
    func numberOfRowsForImageItem(isCanEdit: Bool) -> Int {
//        isCanEdit ? (imagesCount >= 9 ? 9 : imagesCount + 1) : imagesCount
        isCanEdit ? imagesCount + 1 : imagesCount
    }
    
    func isAddImageCell(isCanEdit: Bool, at indexPath: IndexPath) -> Bool {
//        isCanEdit && imagesCount < 9 && indexPath.item == imagesCount
        isCanEdit && indexPath.item == imagesCount
    }
    
    func deleteButtonHidden(isCanEdit: Bool, at indexPath: IndexPath) -> Bool {
        !isCanEdit
            ? true
            : (isAddImageCell(isCanEdit: isCanEdit, at: indexPath) ? true : false)
    }
    
    func addImage(with model: SEUploadFileModel) {
        var images = info.picList ?? []
        images.append(model)
        info.picList = images
    }
    
    func dataToImage(at indexPath: IndexPath) -> UIImage? {
        guard let imageData = info.picList?[indexPath.item].imageData else { return nil }
        return UIImage(data: imageData)
    }
    
    var imageIds: String {
        guard let array = info.picList, array.count > 0 else { return "" }
        return array.compactMap { $0.resourceId }.joined(separator: ",")
    }
    
    // MARK: - 消息列表
    
    var messageCount: String? {
        let sum = inquiryInfoList.compactMap { $0.unReadCount }.reduce(0, +)
        if sum <= 0 {
            return nil
        } else if sum > 99 {
            return "99+"
        } else {
            return "\(sum)"
        }
    }
    
    var unReadHidden: Bool { info.unReadCount <= 0 }
    var unReadCount: String { "\(info.unReadCount)" }
    
    var content: String? {
        switch info.msgType {
        case .image:         return "[图片]"
        case .prescription:  return "[诊断结果]"
        case .checkReport:   return "[眼科检查AI报告]"
        case .fileAuthorize: return "[调阅健康档案确认]"
        case .endInquiry:    return "[结束问诊确认]"
        case .videoCall:     return "[视频通话]"
        default:             return info.content
        }
    }
    
    func getDetailOfGuideInquiry() {
        SEHttpManager.shared.request(SEHospitalizeAPI.detailOfGuideInquiry(id: info.id ?? ""), model: SEInquiryInfo.self, withLoading: withLoading) { (model, httpStatus) in
            switch httpStatus {
            case .success:
                if let model = model {
                    self.info = model
                }
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            self.updateData?(httpStatus)
        }
    }
}

extension SEInquiryInfoViewModel {
    func decodeMessages() {
        guard let saveModel = UserDefaults.standard.object(forKey: "messages") as? Data else { return }
        
        let jsonDecoder = JSONDecoder()
        
        guard let models = try? jsonDecoder.decode([SEInquiryInfo].self, from: saveModel) else { return }
        
        inquiryInfoList = models
        
        updateData?(.success)
    }
    
    private func encodeMessages() {
        let jsonEncoder = JSONEncoder()
        
        guard let saveData = try? jsonEncoder.encode(inquiryInfoList) else { return }
        
        UserDefaults.standard.set(saveData, forKey: "messages")
    }
}
